<html>
<head><meta charset="utf-8"><title>inherent type aliases · t-lang · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/index.html">t-lang</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/inherent.20type.20aliases.html">inherent type aliases</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="209242996"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/inherent%20type%20aliases/near/209242996" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mikail Bagishov <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/inherent.20type.20aliases.html#209242996">(Sep 06 2020 at 21:46)</a>:</h4>
<p>(Let me provide long introduction, because I don't know correct terminology so I want to describe my intent).<br>
Currently following is allowed:</p>
<div class="codehilite"><pre><span></span><code><span class="k">trait</span><span class="w"> </span><span class="n">Tr</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">type</span> <span class="nc">A</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">struct</span> <span class="nc">Foo</span><span class="p">;</span><span class="w"></span>

<span class="k">impl</span><span class="w"> </span><span class="n">Tr</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Foo</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">type</span> <span class="nc">A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">();</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>


<p>But following is denied:</p>
<div class="codehilite"><pre><span></span><code><span class="k">struct</span> <span class="nc">Foo</span><span class="p">;</span><span class="w"></span>
<span class="k">impl</span><span class="w"> </span><span class="n">Foo</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">type</span> <span class="nc">A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">();</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>


<p>Issue <a href="https://github.com/rust-lang/rust/issues/8995">#8995</a> is marked as lazy normalization. I know pretty nothing about it (except that it is part of type system), so it is possible that I'm completely wrong.</p>
<p>However is seems that this feature can be implemented almost entirely via desugaring.</p>
<div class="codehilite"><pre><span></span><code><span class="k">struct</span> <span class="nc">Spam</span><span class="o">&lt;</span><span class="n">Foo</span><span class="p">,</span><span class="w"> </span><span class="n">Bar</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">N</span>: <span class="kt">usize</span><span class="o">&gt;</span><span class="p">;</span><span class="w"></span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">Foo</span>: <span class="nc">Debug</span><span class="p">,</span><span class="w"> </span><span class="n">Bar</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">N</span>: <span class="kt">usize</span><span class="o">&gt;</span><span class="w"> </span><span class="n">Spam</span><span class="w">  </span><span class="k">where</span><span class="w"> </span><span class="p">[</span><span class="n">B</span><span class="p">,</span><span class="w"> </span><span class="n">N</span><span class="p">]</span>: <span class="nc">Display</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">type</span> <span class="nc">A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">Foo</span><span class="p">,</span><span class="w"> </span><span class="n">Bar</span><span class="p">,</span><span class="w"> </span><span class="p">[();</span><span class="w"> </span><span class="n">N</span><span class="p">]);</span><span class="w"></span>

<span class="w">   </span><span class="k">fn</span> <span class="nf">normal_func</span><span class="p">()</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="c1">// gets desugared to</span>
<span class="c1">// helper trait</span>
<span class="k">trait</span><span class="w"> </span><span class="n">__Spam1</span><span class="o">&lt;</span><span class="n">Foo</span><span class="p">,</span><span class="w"> </span><span class="n">Bar</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">N</span>: <span class="kt">usize</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">type</span> <span class="nc">A</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">Spam</span><span class="o">&lt;</span><span class="n">Foo</span><span class="p">,</span><span class="w"> </span><span class="n">Bar</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">N</span>: <span class="kt">usize</span><span class="o">&gt;</span><span class="p">;</span><span class="w"></span>

<span class="k">impl</span><span class="o">&lt;</span><span class="n">Foo</span>:<span class="nc">Debug</span><span class="p">,</span><span class="w"> </span><span class="n">Bar</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">N</span>: <span class="kt">usize</span><span class="o">&gt;</span><span class="w"> </span><span class="n">__Spam1</span><span class="o">&lt;</span><span class="n">Foo</span><span class="p">,</span><span class="w"> </span><span class="n">Bar</span><span class="p">,</span><span class="w"> </span><span class="n">N</span><span class="o">&gt;</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Spam</span><span class="o">&lt;</span><span class="n">Foo</span><span class="p">,</span><span class="w"> </span><span class="n">Bar</span><span class="p">,</span><span class="w"> </span><span class="n">N</span><span class="o">&gt;</span><span class="w"> </span><span class="k">where</span><span class="w"> </span><span class="p">[</span><span class="n">Bar</span><span class="p">;</span><span class="w"> </span><span class="n">N</span><span class="p">]</span>: <span class="nc">Display</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="c1">//  transferred to the trait</span>
<span class="w">    </span><span class="k">type</span> <span class="nc">A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">Foo</span><span class="w"> </span><span class="p">,</span><span class="w"> </span><span class="n">Bar</span><span class="p">,</span><span class="w"> </span><span class="p">[();</span><span class="w"> </span><span class="n">N</span><span class="p">]);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">impl</span><span class="o">&lt;</span><span class="n">Foo</span>: <span class="nc">Debug</span><span class="p">,</span><span class="w"> </span><span class="n">Bar</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">N</span>: <span class="kt">usize</span><span class="o">&gt;</span><span class="w"> </span><span class="n">Spam</span><span class="o">&lt;</span><span class="n">Foo</span><span class="p">,</span><span class="w"> </span><span class="n">Bar</span><span class="p">,</span><span class="w"> </span><span class="n">N</span><span class="o">&gt;</span><span class="w"> </span><span class="k">where</span><span class="w"> </span><span class="p">[</span><span class="n">Bar</span><span class="p">;</span><span class="w"> </span><span class="n">N</span><span class="p">]</span>: <span class="nc">Display</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="c1">// left as-is</span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">normal_func</span><span class="p">()</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>


<p>This desugaring takes place for each impl block separately.<br>
For each<code> impl</code> rustc generates special trait with random or otherwise unnameable name (as for closures, <code>async</code> blocks, generator blocks, etc). Bounds on this trait definition are the same as bounds on type definition. This trait declares all types that were defined by the current impl block.</p>
<p>Also rustc generates this trait implementation for type in question. Bounds in this implementation are copied from the impl block. Definitions of types are moved to this trait implementation. Definition of "normal" items (i.e. functions) is left in the impl block.</p>
<p>Also, name resolution is modified: all these helper traits are somehow "attached" to the type: if some scope imports type, all these traits get imported too, so scope can use that types.</p>
<p>I understand that this particular approach is rather hacky (esp. nameres part). I just want to say: it <strong>seems</strong> that <a href="https://github.com/rust-lang/rust/issues/8995">#8995</a> can be resolved without typesystem-level changes.</p>
<p>Am i wrong somewhere?</p>



<a name="209260692"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/inherent%20type%20aliases/near/209260692" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> isHavvy <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/inherent.20type.20aliases.html#209260692">(Sep 07 2020 at 06:17)</a>:</h4>
<p>I wanted to implement this myself (it's a glaring hole in our consistency story), but was told to wait for name resolution to be refactored properly. That was two Rustconfs ago, so I'm not sure what's changed since then.</p>



<a name="213839891"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/inherent%20type%20aliases/near/213839891" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/inherent.20type.20aliases.html#213839891">(Oct 19 2020 at 20:21)</a>:</h4>
<p>I would like this but yeah impl challenge :)</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>